package com.github.cakin.shiro.chapter23.service;

import com.github.cakin.shiro.chapter23.dao.AuthorizationDao;
import com.github.cakin.shiro.chapter23.entity.Authorization;
import com.github.cakin.shiro.chapter23.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * @className: AuthorizationServiceImpl
 * @description: 授权服务实现类
 * @date: 2020/6/1
 * @author: cakin
 */
@Service

public class AuthorizationServiceImpl implements AuthorizationService {
    /**
     * authorizationDao
     */
    @Autowired
    private AuthorizationDao authorizationDao;
    /**
     * userService
     */
    @Autowired
    private UserService userService;
    /**
     * roleService
     */
    @Autowired
    private RoleService roleService;
    /**
     * appService
     */
    @Autowired
    private AppService appService;

    /**
     * 功能描述：创建一条授权记录
     *
     * @param authorization 授权信息
     * @return Authorization 返回创建的授权信息
     * @author cakin
     * @date 2020/6/1
     */
    public Authorization createAuthorization( Authorization authorization ) {
        return merge(authorization);
    }

    /**
     * 功能描述：更新一条授权记录
     *
     * @param authorization 授权信息
     * @return Authorization 返回更新的授权信息
     * @author cakin
     * @date 2020/6/1
     */
    public Authorization updateAuthorization( Authorization authorization ) {
        return merge(authorization);
    }
    /**
     * 功能描述：合并权限
     *
     * @author cakin
     * @date 2020/6/1
     * @param authorization 需要合并的权限
     * @return Authorization 合并后的权限
     */
    public Authorization merge( Authorization authorization ) {
        Authorization dbAuthorization = authorizationDao.findByAppUser(authorization.getAppId(), authorization.getUserId());
        if (dbAuthorization == null) {
            // 如果数据库中不存在相应记录,直接新增
            return authorizationDao.createAuthorization(authorization);
        }
        // 如果是同一条记录直接更新即可
        if (dbAuthorization.equals(authorization)) {
            return authorizationDao.updateAuthorization(authorization);
        }
        // 否则合并角色
        for (Long roleId : authorization.getRoleIds()) {
            if (!dbAuthorization.getRoleIds().contains(roleId)) {
                dbAuthorization.getRoleIds().add(roleId);
            }
        }
        // 如果没有角色 直接删除记录即可
        if (dbAuthorization.getRoleIds().isEmpty()) {
            authorizationDao.deleteAuthorization(dbAuthorization.getId());
            return dbAuthorization;
        }
        // 更新
        return authorizationDao.updateAuthorization(dbAuthorization);
    }
    /**
     * 功能描述：删除权限
     *
     * @author cakin
     * @date 2020/6/1
     * @param authorizationId 授权Id
     */
    public void deleteAuthorization( Long authorizationId ) {
        authorizationDao.deleteAuthorization(authorizationId);
    }

    /**
     * 功能描述：根据id找到对应的授权记录
     *
     * @param authorizationId 授权记录的id
     * @return Authorization 返回更新的授权信息
     * @author cakin
     * @date 2020/6/1
     */
    public Authorization findOne( Long authorizationId ) {
        return authorizationDao.findOne(authorizationId);
    }

    /**
     * 功能描述：查找所有的授权记录
     *
     * @return List<Authorization> 授权列表
     * @author cakin
     * @date 2020/6/1
     */
    public List<Authorization> findAll() {
        return authorizationDao.findAll();
    }

    /**
     * 根据AppKey和用户名查找其角色集
     *
     * @param username 用户名
     * @param appKey   app键
     * @return Set<String> 角色集
     */
    public Set<String> findRoles( String appKey, String username ) {
        User user = userService.findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        Long appId = appService.findAppIdByAppKey(appKey);
        if (appId == null) {
            return Collections.EMPTY_SET;
        }
        Authorization authorization = authorizationDao.findByAppUser(appId, user.getId());
        if (authorization == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findRoles(authorization.getRoleIds().toArray(new Long[0]));
    }

    /**
     * 根据AppKey和用户名查找权限字符串
     *
     * @param username 用户名
     * @param appKey   app键
     * @return Set<String> 权限集
     */
    public Set<String> findPermissions( String appKey, String username ) {
        User user = userService.findByUsername(username);
        if (user == null) {
            return Collections.EMPTY_SET;
        }
        Long appId = appService.findAppIdByAppKey(appKey);
        if (appId == null) {
            return Collections.EMPTY_SET;
        }
        Authorization authorization = authorizationDao.findByAppUser(appId, user.getId());
        if (authorization == null) {
            return Collections.EMPTY_SET;
        }
        return roleService.findPermissions(authorization.getRoleIds().toArray(new Long[0]));
    }
}
